package com.thinkcoder.request;

import com.thinkcoder.constant.AuthConstants;
import com.thinkcoder.exception.ServiceException;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.ToString;

import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@Getter
@AllArgsConstructor
@ToString
public class ApiRequest {

    /**
     * 正常的接口请求,Http请求或者Rpc请求
     */
    private String originUrl;

    /**
     * 调用方身份标识
     */
    private String appKey;

    /**
     * 调用方调用时的时间戳
     */
    private long timeStamp;

    /**
     * 调用方调用时的随机数
     */
    private Integer nonce;

    /***
     * 从url中取出ApiRequest请求对象
     *
     * @param url
     * @return
     */
    public static ApiRequest createFromFullUrl(String url){


        Map<String, String> paramMap = resolveUrl(url);

        if(!url.contains("?")){
            throw new ServiceException(10010,"url不含有认证信息");
        }

        String originUrl = url.split("\\?")[0];
        originUrl=
                buildOriginalUrl(originUrl,paramMap);

        String appKey = "";
        long timeStamp = 0;
        Integer nonce=0;

        if(paramMap != null && paramMap.size()>0){
            appKey=paramMap.get(AuthConstants.APP_KEY);
            timeStamp=Long.parseLong(paramMap.get(AuthConstants.TIME_STAMP));
            nonce=Integer.parseInt(paramMap.get(AuthConstants.NONCE));
        }

        ApiRequest apiRequest = new ApiRequest(originUrl, appKey, timeStamp, nonce);
        return apiRequest;
    }

    private static String buildOriginalUrl(String originalUrl, Map<String, String> paramsMap) {

        StringBuilder sb = new StringBuilder(originalUrl).append("?");
        for (Map.Entry<String, String> entry : paramsMap.entrySet()){
            String key = entry.getKey();
            if (!AuthConstants.APP_KEY.equals(key)
                    && !AuthConstants.TIME_STAMP.equals(key) && !AuthConstants.NONCE.equals(key)) {
                sb.append(key).append("=").append(entry.getValue());
            }
        }
        return sb.toString();
    }

    /***
     * 从url中解析出参数
     * www.xxx.com/getUser?appKey=abc&timeStamp=12345555&nonce=124154546
     *
     * @param url
     * @return
     */
    private static Map<String,String> resolveUrl(String url){

        if(url==null || url.length()<=0){
            return null;
        }

        try{
            //拿到?后的值：appKey=abc&timeStamp=12345555&nonce=124154546
            String substr = url.substring(url.indexOf("?") + 1);
            String[] paramsKvArr = substr.split("&");
            if(paramsKvArr == null || paramsKvArr.length<1){
                return null;
            }

            //将上述值变为map结构：<appKey,abc>
            Map<String,String> paramsMap = new HashMap<>();
            for(String paramsKvStr:paramsKvArr){
                paramsMap.put(getKey(paramsKvStr),getValue(paramsKvStr));
            }
            return paramsMap;
        }catch (Exception e){
            throw new ServiceException(10010,"解析URL出错");
        }

    }

    //从url中解析出key值
    private static String getKey(String paramsKvStr) {
        String key = paramsKvStr.substring(0,paramsKvStr.indexOf("="));
        return key;
    }

    //从url中解析出value值
    private static String getValue(String paramsKvStr) {
        String value = paramsKvStr.substring(paramsKvStr.indexOf("=")+1);
        return value;
    }

    public static ApiRequest buildApiRequest(Map<String,String> paramsMap){
        if(paramsMap == null || paramsMap.size()<1){
            return null;
        }
        String originUrl = paramsMap.containsKey(AuthConstants.ORIGIN_URL) ? paramsMap.get(AuthConstants.ORIGIN_URL) : null;
        String appKey = paramsMap.containsKey(AuthConstants.APP_KEY) ? paramsMap.get(AuthConstants.APP_KEY) : null;
        long timeStamp = paramsMap.containsKey(AuthConstants.TIME_STAMP) ? Long.parseLong(paramsMap.get(AuthConstants.TIME_STAMP)) : null;
        Integer nonce = paramsMap.containsKey(AuthConstants.NONCE) ? Integer.parseInt(paramsMap.get(AuthConstants.NONCE) ): null;
        return new ApiRequest(originUrl,appKey,timeStamp,nonce);
    }

}
